﻿using System.Text.Json;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System;

namespace TaskProcessDemo
{
    internal class Program
    {
        private static string logFilePath;
        private static readonly HttpClient httpClient = new();

        static async Task Main(string[] args)
        {
            // 初始化日志文件路径
            string logDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logs");
            if (!Directory.Exists(logDir))
            {
                Directory.CreateDirectory(logDir);
            }
            logFilePath = Path.Combine(logDir, $"task_{DateTime.Now:yyyyMMdd_HHmmss}.log");

            if (args.Length != 3)
            {
                LogMessage("输入参数错误, Usage: TaskProcessDemo <ServePort> <TaskArgs> <ParamArgs> ");
                return;
            }

            //打印输入参数
            LogMessage($"输入参数: ServePort={args[0]}, TaskArgs={args[1]}, ParamArgs={args[2]}");

            try
            {
                //当前进程启动时传递的参数模型
                var processArgs = new ProcessArgs(
                     int.Parse(args[0]),
                     args[1],
                     args[2]
                 );

                LogMessage($"任务启动: ID={processArgs.TaskArgs.TaskId}, 名称={processArgs.TaskArgs.TaskName}");

                // 调用模拟任务执行函数
                await SimulateTaskExecution(processArgs);

                LogMessage("程序执行完成");
            }
            catch (Exception ex)
            {
                LogMessage($"参数解析失败: {ex.Message}");
                return;
            }
        }

        /// <summary>
        /// 模拟任务执行函数
        /// 总共执行25秒，分五步
        /// 1. 第一步：发送运行状态更新请求
        /// 2-4. 中间三步：每步发送进度更新请求
        /// 5. 最后一步：发送完成状态更新请求
        /// </summary>
        private static async Task SimulateTaskExecution(ProcessArgs processArgs)
        {
            try
            {
                // 第一步: 发送运行状态更新请求（0秒）
                await SendTaskStatusUpdate(processArgs, TaskStatus.RUNNING, "任务开始执行...");
                LogMessage($"步骤1/7: 任务开始执行,任务内部执行参数: {processArgs.ParamArgs}");

                await Task.Delay(3000);
                // 第二步：发送进度更新请求（3秒）- 20%完成
                await SendTaskProgressUpdate(processArgs, 0.2f, $"加载数据参数...");
                LogMessage("步骤2/7: 进度20%");

                await Task.Delay(3000);
                // 第三步：发送进度更新请求（6秒）- 40%完成
                await SendTaskProgressUpdate(processArgs, 0.4f, $"开始处理数据...");
                LogMessage("步骤3/7: 进度40%");

                await Task.Delay(3000);
                // 第四步：发送进度更新请求（9秒）- 75%完成
                await SendTaskProgressUpdate(processArgs, 0.6f, $"分析处理数据中...");
                LogMessage("步骤4/7: 进度60%");

                await Task.Delay(6000);
                // 第五步：发送进度更新请求（15秒）- 80%完成
                await SendTaskProgressUpdate(processArgs, 0.8f, $"数据转换中...");
                LogMessage("步骤5/7: 进度80%");

                await Task.Delay(6000);
                // 第六步：发送进度更新请求（21秒）- 99%完成
                await SendTaskProgressUpdate(processArgs, 0.99f, $"数据处理完成正在保存...");
                LogMessage("步骤6/7: 进度99%");

                await Task.Delay(3000);
                // 第六步：发送完成状态更新请求（24秒）
                await SendTaskStatusUpdate(processArgs, TaskStatus.COMPLETED, $"任务执行完成!");
                LogMessage("步骤7/7: 任务完成");
            }
            catch (Exception ex)
            {
                // 出错时发送失败状态
                await SendTaskStatusUpdate(processArgs, TaskStatus.FAILED, $"任务执行失败: {ex.Message}");
                LogMessage($"任务执行出错: {ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 发送任务状态更新请求
        /// </summary>
        private static async Task SendTaskStatusUpdate(ProcessArgs processArgs, TaskStatus status, string message)
        {
            try
            {
                var statusRequest = new TaskStatusRequest
                {
                    TaskId = processArgs.TaskArgs.TaskId,
                    Status = status,
                    Message = message  
                };

                string json = JsonSerializer.Serialize(statusRequest);
                var content = new StringContent(json, Encoding.UTF8, "application/json");

                string url = Constant.GetUpdateStatusURL(processArgs.ServePort);
                HttpResponseMessage response = await httpClient.PostAsync(url, content);

                if (response.IsSuccessStatusCode)
                {
                    LogMessage($"状态更新成功: {status}, 消息: {message}");
                }
                else
                {
                    LogMessage($"状态更新失败: HTTP {(int)response.StatusCode} - {response.ReasonPhrase}");
                }
            }
            catch (Exception ex)
            {
                LogMessage($"发送状态更新时出错: {ex.Message}");
            }
        }

        /// <summary>
        /// 发送任务进度更新请求
        /// </summary>
        private static async Task SendTaskProgressUpdate(ProcessArgs processArgs, float progress, string message)
        {
            try
            {
                var progressRequest = new TaskProgressRequest
                {
                    TaskId = processArgs.TaskArgs.TaskId,
                    Progress = progress,
                    Message = message
                };

                string json = JsonSerializer.Serialize(progressRequest);
                var content = new StringContent(json, Encoding.UTF8, "application/json");

                string url = Constant.GetUpdateProgressURL(processArgs.ServePort);
                HttpResponseMessage response = await httpClient.PostAsync(url, content);

                if (response.IsSuccessStatusCode)
                {
                    LogMessage($"进度更新成功: {progress:P0}, 消息: {message}");
                }
                else
                {
                    LogMessage($"进度更新失败: HTTP {(int)response.StatusCode} - {response.ReasonPhrase}");
                }
            }
            catch (Exception ex)
            {
                LogMessage($"发送进度更新时出错: {ex.Message}");
            }
        }

        /// <summary>
        /// 记录日志信息到控制台和文件
        /// </summary>
        /// <param name="message">日志消息</param>
        private static void LogMessage(string message)
        {
            string logMessage = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] {message}";
            
            // 输出到控制台
            Console.WriteLine(logMessage);
            
            // 写入日志文件
            try
            {
                using (StreamWriter writer = new StreamWriter(logFilePath, true, Encoding.UTF8))
                {
                    writer.WriteLine(logMessage);
                }
            }
            catch (Exception ex)
            {
                // 如果写入日志文件失败，至少保证控制台输出正常
                Console.WriteLine($"[警告] 写入日志文件失败: {ex.Message}");
            }
        }
    }
}
